package org.road0329.tools.proto_parse_tool.ems;

import com.alibaba.fastjson.JSON;
import org.road0329.tools.proto_parse_tool.ems.dataobject.DyIotUpData;
import org.road0329.tools.proto_parse_tool.utils.DateUtil;
import org.road0329.tools.proto_parse_tool.utils.ProtocolUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Component
public class ProtocolDyIotWaterUtil {
    private static Logger logger = LoggerFactory.getLogger(ProtocolDyIotWaterUtil.class);

    public static DyIotUpData parseMessage(byte[] msg) {
        if (msg == null || msg.length < 66) {
            return null;
        }
        int index = 2;
        String commAddr = String.format("%02X%02X%02X%02X%02X%02X%02X", msg[index +6], msg[index + 5], msg[index + 4], msg[index + 3],
                msg[index + 2], msg[index + 1], msg[index ]);//地址

        DyIotUpData result = new DyIotUpData();
        result.setMeterNo(commAddr);
        index = 19;
        int count = ProtocolUtils.Unsignd(msg[index]);
        index++;

        String bcd = ProtocolUtils.getStringByBCD(msg, index, 5);
        bcd = ProtocolUtils.reverse(bcd, bcd.length());
        Date firstDataTime = DateUtil.StrToDate(bcd, "yyMMddHHmm");
        result.setFirstDataTime(firstDataTime);
        index += 5;
        int interval = ProtocolUtils.Unsignd(msg[index]);
        result.setInterval((short) interval);
        index += 1;

        List<BigDecimal> cumulantList = new ArrayList<>(count);
        result.setCumulantList(cumulantList);

        BigDecimal value;
        for (int i = 0; i < count; i++) {
            bcd = ProtocolUtils.getStringByBCD(msg, index, 5);
            bcd = ProtocolUtils.reverse(bcd, bcd.length());
            value = ProtocolUtils.valueToDecimal(Long.parseLong(bcd), 4);
            cumulantList.add(value);
            index += 5;
        }
        //累积量
        bcd = ProtocolUtils.getStringByBCD(msg, index, 5);
        bcd = ProtocolUtils.reverse(bcd, bcd.length());
        BigDecimal currentCumulant = ProtocolUtils.valueToDecimal(Long.parseLong(bcd), 4);
        result.setCurrentCumulant(currentCumulant);
        index += 5;

        result.setInstantFlow(ProtocolUtils.byteToBigDecimal(msg, index, 2, 2));
        index += 2;
        result.setSensorSignalStrengthA(ProtocolUtils.byteToShort(msg[index + 1], msg[index]));
        index += 2;
        result.setSensorSignalStrengthB(ProtocolUtils.byteToShort(msg[index + 1], msg[index]));
        index += 2;
        result.setTemperature(msg[index]);
        index += 1;

        bcd = ProtocolUtils.getStringByBCD(msg, index, 2);
        bcd = ProtocolUtils.reverse(bcd, bcd.length());
        value = ProtocolUtils.valueToDecimal(Long.parseLong(bcd), 2);
        result.setVoltage(value.floatValue());
        index += 2;

        bcd = ProtocolUtils.getStringByBCD(msg, index, 1);
        result.setBaseCsq(Short.parseShort(bcd));
        index += 1;

        boolean sign = (msg[index + 1] & 0x80) > 0;
        result.setRsrp((short)(ProtocolUtils.byteToShort((byte)(msg[index + 1] & 0x7f), msg[index]) * (sign ? -1 : 1)));
        index += 2;

        result.setRsrq((short) ProtocolUtils.byteToSignInt(msg[index + 1], msg[index]));
        index += 2;

        result.setSnr((short) ProtocolUtils.byteToSignInt(msg[index + 1], msg[index]));
        index += 2;

        result.setEcl(msg[index]);
        index += 1;

        bcd = ProtocolUtils.getStringByBCD(msg, index, 2);
        result.setBasePci(bcd);
        index += 2;

        bcd = ProtocolUtils.getStringByBCD(msg, index, 8);
        result.setImei(bcd);
        index += 8;

        bcd = ProtocolUtils.getStringByBCD(msg, index, 8);
        result.setImsi(bcd);
        index += 8;

        result.setSuccessCount(ProtocolUtils.byteToShort(msg[index + 1], msg[index]));
        index += 2;

        result.setFailCount(ProtocolUtils.byteToShort(msg[index + 1], msg[index]));
        index += 2;

        bcd = ProtocolUtils.getStringByBCD(msg, index, 7);
        bcd = ProtocolUtils.reverse(bcd, bcd.length());
        Date dataTime = DateUtil.StrToDate(bcd, "yyyyMMddHHmmss");
        result.setDataTime(dataTime);
        index += 7;

        byte[] status = new byte[2];
        System.arraycopy(msg, index, status, 0, 2);
        result.setStatus(String.format("%02X%02X", status[0], status[1]));
        index += 2;
        short batteryStatus = 0;
        if (!"FF".equalsIgnoreCase(String.format("%02X", status[0]))) {
            if ((status[0] & 0x04) != 0x00) {//电池电压欠压
                batteryStatus = 1;
            }
        }
        result.setBatteryStatus(batteryStatus);

        short valveStatus = (short) (status[0] & 0x01);
        result.setValveStatus(valveStatus);

        result.setAlarm(String.format("%02X %02X %02X", msg[index], msg[index + 1], msg[index + 2]));
        index += 3;

        bcd = ProtocolUtils.getStringByBCD(msg, index, 2);
        bcd = ProtocolUtils.reverse(bcd, bcd.length());
        result.setHardwareVersion(bcd.substring(0, 2) + "." + bcd.substring(2));
        index += 2;

        bcd = ProtocolUtils.getStringByBCD(msg, index, 2);
        bcd = ProtocolUtils.reverse(bcd, bcd.length());
        result.setSoftwareVersion(bcd.substring(0, 2) + "." + bcd.substring(2));
        index += 2;
        logger.debug("端云水表9023 解析结果:{}", JSON.toJSONString(result));
        return result;
    }
}
